#!/usr/bin/env python
import random,sys, math
import numpy as np
	from pympler.classtracker import ClassTracker
	from pympler.classtracker_stats import Stats
from operator import itemgetter
import spacesaving as SS
from util import Timer
from time import gmtime, strftime
import pickle

def round_slice_and_sort(_list,max):
	lim = min(max,len(_list))
	return sorted(map(lambda x: (x[0], round(x[1],3)), _list),key=itemgetter(1),reverse=True)[:lim]


def count_exact(a,limit):
	count = {}
	for item in a :
		if item[0] not in count :
			count[item[0]] = 0.0
		count[item[0]] += (item[1])

	exact = []
	for k,v in count.iteritems() :
		exact.append((k,round(v,3)))

	exact=sorted(exact,key=itemgetter(1),reverse=True)
	return exact[:limit]

def trace(a, results, eps,k,limit) :

#	res = count_exact(a, limit)
	_splits = [0.0,0.0,0.0]
	time = str(k) + "\t"
	it = 2
	for i in range(it) :
#		time = str(k) + "\t"
#			input = base * math.pow(2, i)
#			zipfdist = list(np.random.zipf(skew, input))
#			a = []
#			for el in zipfdist :
#				a.append(("".join(["a",str(el)]), random.random()))
		with Timer() as t :
			ssb = SS.SpaceSavingBucket(eps)
#			tracker.track_object(ssb,resolution_level=2)
			for item in a :
				ssb.add(item)
		_split = t.interval
		_splits[0] += _split

#		time +=  "%.03f\t" % _split
		results["ssb"][i] = (round_slice_and_sort(ssb.get_summary('list'),limit),round(_split,5),eps)

#			ssb.print_trace()
		with Timer() as t :
			ssbb = SS.SpaceSavingBucketBuffer(eps, k)
#			tracker.track_object(ssbb,resolution_level=2)
			for item in a :
				ssbb.add(item)
		_split = t.interval
		_splits[1] += _split
#		time += "%.03f\t" % _split
		results["ssbb"][i] = (round_slice_and_sort(ssbb.get_summary('list'),limit), round(_split, 5))

		with Timer() as t :
			sshb = SS.SpaceSavingHashBuffer(eps, k)
#			tracker.track_object(sshb,resolution_level=2)
			for item in a :
				sshb.add(item)
		_split = t.interval
		_splits[2] += _split
#		time += "%.03f" % _split
		results["sshb"][i] = (round_slice_and_sort(sshb.get_summary('list'),limit), round(_split,5))
		tracker.create_snapshot(description=" : ".join(["k", str(k),"i ", str(i)]))

	_splits = list(map(lambda x : x/it, _splits))
	print "%s\t%.04f\t%.04f\t%.04f" % (str(k),_splits[0],_splits[1], _splits[2])
	return results
#	pickle.dump(results, foutput)
#	foutput.close()
#	tracker.stats.dump_stats(prof, False)

def main() :

	files = ['input_zipf_4000000_1.5','input_zipf_4000000_2.0','input_zipf_4000000_2.5']
	out_dir = "../out/"
	data_dir = "../../data/"

	for filename in files :
		limit = 100
		skew = filename.split('_')[3]
		inputsize = filename.split('_')[2]

		ts = strftime("%d%m%y-%H.%M.%S", gmtime())
		_input = open(data_dir +  filename)
		a = pickle.load(_input)
		RESULTS = []
		global tracker
		tracker = ClassTracker()
		tracker.track_class(SS.SpaceSavingBucket, resolution_level=2)
		tracker.track_class(SS.SpaceSavingBucketBuffer, resolution_level=2)
		tracker.track_class(SS.SpaceSavingHashBuffer, resolution_level=2)
		print "k\tSSB\tSSBB\tSSHB"

		for j in range(4) :
			x = int(math.pow(10, j))
			for i in range (1,10) :
				if j == 0 and i == 1 : continue
				k = int(i * x)
				eps = float(1.0/k)
				results = {}
				results["info"] = {"input":inputsize, "eps": eps, "k": k, "skew": skew}
				results["ssb"] = {}
				results["ssbb"] ={}
				results["sshb"] = {}
				results = trace(a, results, eps, k, limit)
				RESULTS.append(results)

		fprofile = out_dir + "_".join([ts,str(inputsize), str(skew), "profile"])
		prof = open(fprofile ,'w')
		tracker.stats.dump_stats(prof, False)

		foutput = out_dir + "_".join([ts,str(inputsize), str(skew), "output"])
		foutput = open(foutput,'w')
		pickle.dump(RESULTS, foutput)
		foutput.close()
#def trace(a, results, eps,k,limit) :

main()